<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      rel="stylesheet"
      href="https://at.alicdn.com/t/c/font_2579455_c6xlnvkj0j.cssspm=a313x.7781069.1998910419.53&file=font_2579455_c6xlnvkj0j.css"
    />
    <title>拖拽</title>
    <style>
      body {
        background-color: #000;
      }
      .list {
        width: 300px;
        height: 360px;
        /* padding: 20px 0; */
        margin: 100px auto 0;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
      }
      .list-item {
        width: 100%;
        display: flex;
        align-items: center;
        padding: 0 16px;
        border-radius: 10px;
        /* margin-bottom: 20px; */
        background-color: var(--color);
      }
      .constellation {
        line-height: 2.5em;
        font-size: 20px;
        color: #fff;
      }
      .list-item-img {
        width: 30px;
        height: 30px;
      }
      .list-item-title {
        margin-left: 20px;
        color: #fff;
      }
      /* 移动动画class */
      .list-item.moving {
        background-color: transparent;
        border: 2px dashed #ccc;
      }
    </style>
  </head>
  <body>
    <div class="list">
      <div class="list-item" draggable="true" style="--color: #e63e31">
        <i class="iconfont icon-shuangyuzuo constellation"></i>
        <span class="list-item-title">双鱼座</span>
      </div>
      <div class="list-item" draggable="true" style="--color: #70d265">
        <i class="iconfont icon-shuipingzuo constellation"></i>
        <span class="list-item-title">水平座</span>
      </div>
      <div class="list-item" draggable="true" style="--color: #f0e941">
        <i class="iconfont icon-mojiezuo constellation"></i>
        <span class="list-item-title">摩羯座</span>
      </div>
      <div class="list-item" draggable="true" style="--color: #da8218">
        <i class="iconfont icon-chunvzuo constellation"></i>
        <span class="list-item-title">处女座</span>
      </div>
      <div class="list-item" draggable="true" style="--color: #7ff0ec">
        <i class="iconfont icon-shizizuo constellation"></i>
        <span class="list-item-title">狮子座</span>
      </div>
    </div>
    <script>
      // 操作dom元素
      const list = document.querySelector('.list')
      const item = document.querySelectorAll('.list-item')

      // 判断当前元素
      let source_node
      // 开始拖动
      list.ondragstart = (e) => {
        source_node = e.target
        recode(item)
        setTimeout(() => {
          e.target.classList.add('moving')
        }, 0)
        // 设置拖动效果
        e.dataTransfer.effectAllowed = 'move'
      }
      // 拖动在有效目标
      list.ondragover = (e) => {
        // 防止默认情况下允许删除
        e.preventDefault()
      }
      // 拖拽放入有效目标触发
      list.ondragenter = (e) => {
        e.preventDefault()
        console.log(e.target.id, list)
        if (e.target === list || e.target === source_node) {
          return false
        }
        const childer = Array.from(list.children)
        const sourceIndex = childer.indexOf(source_node)
        const targetIndex = childer.indexOf(e.target)
        console.log(sourceIndex, targetIndex)
        if (sourceIndex < targetIndex) {
          // 从上往下拖动
          console.log(111,source_node,e.target.nextElementSibling)
          //  if()
          list.insertBefore(source_node, e.target.nextElementSibling)
        } else {
          // 从下往上拖动
          console.log(222,source_node, e.target)
          if (!e.target == null || source_node == null) {
            return
          }
          list.insertBefore(source_node, e.target)
        }
        last([e.target, source_node])
      }
      // 拖放结束
      list.ondragend = (e) => {
        e.target.classList.remove('moving')
      }
      // 重新计算位置
      function recode(eleAll) {
        // getBoundingClientRect 返回元素对于视口信息
        for (let i = 0; i < eleAll.length; i++) {
          const { top, left } = eleAll[i].getBoundingClientRect()
          eleAll[i]._top = top
          eleAll[i]._left = left
        }
      }
      // 添加移动动画效果
      function last(eleAll) {
        for (let i = 0; i < eleAll.length; i++) {
          const dom = eleAll[i]
          const { top, left } = dom.getBoundingClientRect()
          console.log(eleAll[i], dom._top-top)
          if (dom._left) {
            dom.style.transform = `translate3d(${dom._left - left}px,${
              dom._top - top
            }px,0px)`
            // 重绘动画
            let rafId = requestAnimationFrame(function () {
              dom.style.transition = `transform 0.3s ease-out`
              dom.style.transform = 'none'
            })
            dom.addEventListener('transitionend', () => {
              dom.style.transition = 'none'
              // 取消requestAnimationFrame调用请求
              cancelAnimationFrame(rafId)
            })
          }
        }
      }
    </script>
  </body>
</html>
